//
//  NSArray+SafeArray.m
//  KanManHua
//
//  Created by Banning on 2017/9/19.
//  Copyright © 2017年 KanManHua. All rights reserved.
//

#import "NSArray+Safe.h"
#import <objc/runtime.h>

@implementation NSArray (Safe)

- (NSString *)stringAtIndex:(NSUInteger)index{
    id object = [self safeObjectAtIndex:index];
    if (object != nil) {
        if ([object isKindOfClass:[NSNumber class]]) {
            return [object stringValue];
        }
        
        if ([object isKindOfClass:[NSString class]]) {
            return [object stringValue];
        }
    }
    return nil;
}

- (id)safeObjectAtIndex:(NSUInteger)index{
    NSUInteger count = self.count;
    if (count > index) {
        if ([self respondsToSelector:@selector(objectAtIndex:)]) {
            return [self objectAtIndex:index];
        }
        return nil;
    }
    return nil;
}

@end


@interface NSMutableArray ()

@property (nonatomic, strong) NSRecursiveLock * km_safe_arr_lock;

@end

@implementation NSMutableArray (SafeAddValue)


- (void)setKm_safe_arr_lock:(NSRecursiveLock *)km_safe_arr_lock
{
    objc_setAssociatedObject(self, @"km_safe_arr_lock",km_safe_arr_lock , OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSRecursiveLock *)km_safe_arr_lock
{
    NSRecursiveLock * lock = objc_getAssociatedObject(self, @"km_safe_arr_lock");
    if (nil == lock) {
        lock = [NSRecursiveLock new];
        [self setKm_safe_arr_lock:lock];
    }
    return lock;
}

- (void)addSafeObject:(id)anObject{
    if (anObject != nil) {
        if ([self respondsToSelector:@selector(addObject:)]) {
            [self.km_safe_arr_lock lock];
            [self addObject:anObject];
            [self.km_safe_arr_lock unlock];
        }
    }
}

- (void)insertSafeObject:(id)anObject atIndex:(NSUInteger)index{
    if (anObject != nil) {
        if ([self respondsToSelector:@selector(insertSafeObject:atIndex:)]) {
            [self.km_safe_arr_lock lock];
            [self insertObject:anObject atIndex:index];
            [self.km_safe_arr_lock unlock];
        }
    }
}

- (void)removeSafeObjectAtIndex:(NSUInteger)index{
    if (index < self.count) {
        if ([self respondsToSelector:@selector(removeObjectAtIndex:)]) {
            [self.km_safe_arr_lock lock];
            [self removeObjectAtIndex:index];
            [self.km_safe_arr_lock unlock];
        }
    }
}

@end

TranformWeakObject tranformWeakReference(id object) {
    __weak id weakref = object;
    return ^{
        return weakref;
    };
}

id returnWeakObject(TranformWeakObject tranform) {
    return tranform ? tranform() : nil;
}

@implementation NSMutableArray (Weak)

- (void)weak_addObject:(id)anyObject {
    if (!anyObject) {
        return;
    }
    [self addSafeObject:tranformWeakReference(anyObject)];
}

- (id)weak_getObjectAtIndex:(NSInteger)index {
    id obj = [self safeObjectAtIndex:index];
    if (!obj) {
        return nil;
    }
    return returnWeakObject(obj);
}

@end

